package com.zenithmind.disk.controller;

import com.zenithmind.common.annotation.Log;
import com.zenithmind.common.constant.OperationTypeEnum;
import com.zenithmind.disk.pojo.domain.Files;
import com.zenithmind.disk.pojo.dto.FileDTO;
import com.zenithmind.disk.pojo.query.FileQuery;
import com.zenithmind.disk.pojo.vo.FileVO;
import com.zenithmind.disk.service.FileOperationService;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * 文件管理控制器
 * 遵循单一职责原则：仅负责HTTP请求映射和响应处理
 * 遵循依赖倒置原则：依赖抽象接口而非具体实现
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/files")
@Tag(name = "存储用户文件信息管理")
@RequiredArgsConstructor
@Validated
public class FilesController {

    private final FileOperationService fileOperationService;

    @Log(description = "上传文件", operationType = OperationTypeEnum.UPLOAD)
    @Operation(summary = "上传文件-普通用户")
    @PostMapping("/uploadFile")
    public Result<FileVO> uploadFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam("userId") String userId,
            @RequestParam(value = "parentId", required = false) String parentId) {
        log.info("上传文件请求：文件名={}, 用户ID={}, 父目录ID={}",
                file.getOriginalFilename(), userId, parentId);
        FileVO fileVO = fileOperationService.uploadFile(file, userId, parentId);
        return Result.success(fileVO);
    }

    @Log(description = "创建文件夹", operationType = OperationTypeEnum.ADD)
    @Operation(summary = "创建文件夹-普通用户")
    @PostMapping("/createFolder")
    public Result<FileVO> createFolder(@Validated @RequestBody FileDTO fileDTO) {
        log.info("创建文件夹请求：{}", fileDTO);
        FileVO fileVO = fileOperationService.createFolder(fileDTO);
        return Result.success(fileVO);
    }

    @Log(description = "查询文件列表", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "查询文件列表-普通用户")
    @GetMapping("/listFiles")
    public Result<List<FileVO>> listFiles(
            @RequestParam("userId") String userId,
            @RequestParam(value = "parentId", required = false) String parentId) {
        log.info("查询文件列表请求：用户ID={}, 父目录ID={}", userId, parentId);
        List<FileVO> fileList = fileOperationService.listFiles(userId, parentId);
        return Result.success(fileList);
    }

    @Log(description = "重命名文件", operationType = OperationTypeEnum.UPDATE)
    @Operation(summary = "重命名文件-普通用户")
    @PutMapping("/renameFile")
    public Result<FileVO> renameFile(@Validated @RequestBody FileDTO fileDTO) {
        log.info("重命名文件请求：{}", fileDTO);
        FileVO fileVO = fileOperationService.renameFile(fileDTO);
        return Result.success(fileVO);
    }

    @Log(description = "移动文件", operationType = OperationTypeEnum.UPDATE)
    @Operation(summary = "移动文件-普通用户")
    @PutMapping("/moveFile")
    public Result<Boolean> moveFile(
            @RequestParam("fileId") String fileId,
            @RequestParam("targetId") String targetId,
            @RequestParam("userId") String userId) {
        log.info("移动文件请求：文件ID={}, 目标ID={}, 用户ID={}", fileId, targetId, userId);
        boolean result = fileOperationService.moveFile(fileId, targetId, userId);
        return Result.success(result);
    }

    @Log(description = "删除文件", operationType = OperationTypeEnum.DELETE)
    @Operation(summary = "删除文件-普通用户")
    @DeleteMapping("/deleteFile")
    public Result<Boolean> deleteFile(
            @RequestParam("fileId") String fileId,
            @RequestParam("userId") String userId) {
        log.info("删除文件请求：文件ID={}, 用户ID={}", fileId, userId);
        boolean result = fileOperationService.deleteFile(fileId, userId);
        return Result.success(result);
    }

    @Log(description = "获取文件信息", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "获取文件信息-普通用户")
    @GetMapping("/getFileInfo")
    public Result<FileVO> getFileInfo(@RequestParam("fileId") String fileId) {
        log.info("获取文件信息请求：文件ID={}", fileId);
        FileVO fileVO = fileOperationService.getFileInfo(fileId);
        return Result.success(fileVO);
    }

    @Log(description = "获取文件路径", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "获取文件路径-普通用户")
    @GetMapping("/getFilePath")
    public Result<String> getFilePath(
            @RequestParam("fileId") String fileId,
            @RequestParam("userId") String userId) {
        log.info("获取文件路径请求：文件ID={}, 用户ID={}", fileId, userId);
        String filePath = fileOperationService.getFilePath(fileId, userId);
        return Result.success(filePath);
    }

    @Log(description = "下载文件", operationType = OperationTypeEnum.DOWNLOAD)
    @Operation(summary = "下载文件-普通用户")
    @GetMapping("/downloadFile")
    public void downloadFile(
            @RequestParam("fileId") String fileId,
            @RequestParam("userId") String userId,
            HttpServletResponse response) throws IOException {
        log.info("下载文件请求：文件ID={}, 用户ID={}", fileId, userId);
        fileOperationService.downloadFile(fileId, userId, response);
    }

    @Log(description = "下载文件夹", operationType = OperationTypeEnum.DOWNLOAD)
    @Operation(summary = "下载文件夹-普通用户")
    @GetMapping("/downloadFolder")
    public void downloadFolder(
            @RequestParam("folderId") String folderId,
            @RequestParam("userId") String userId,
            HttpServletResponse response) throws IOException {
        log.info("下载文件夹请求：文件夹ID={}, 用户ID={}", folderId, userId);
        fileOperationService.downloadDirectory(folderId, response);
    }

    @Log(description = "分页查询文件列表", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "分页查询文件列表")
    @GetMapping("/filePage")
    public Result<PageResult<FileVO>> filePage(@Validated FileQuery fileQuery) {
        log.info("分页查询文件列表请求：{}", fileQuery);
        PageResult<FileVO> result = fileOperationService.filePage(fileQuery);
        return Result.success(result);
    }

    @Log(description = "批量删除文件", operationType = OperationTypeEnum.DELETE)
    @Operation(summary = "批量删除文件-管理员")
    @DeleteMapping("/deleteBatchFiles")
    public Result<Boolean> deleteBatchFiles(@Validated @RequestBody List<String> ids) {
        log.info("批量删除文件请求：文件ID列表={}", ids);
        boolean result = fileOperationService.deleteBatchFiles(ids);
        return Result.success(result);
    }

    @Log(description = "添加或修改文件", operationType = OperationTypeEnum.UPDATE)
    @Operation(summary = "添加或修改文件-管理员")
    @PostMapping("/addOrUpdateFile")
    public Result<FileVO> addOrUpdateFile(@Validated @RequestBody Files file) {
        log.info("添加或修改文件请求：{}", file);
        FileVO fileVO = fileOperationService.addOrUpdateFileByAdmin(file);
        return Result.success(fileVO);
    }
}
